package cn.org.xwb.bookmall.admin.controller;

import cn.org.xwb.bookmall.admin.annotation.IsLoginObj;
import cn.org.xwb.bookmall.admin.annotation.IsLoginParam;
import cn.org.xwb.bookmall.admin.service.AdminManagerService;
import cn.org.xwb.bookmall.admin.utils.Convert2PoUtil;
import cn.org.xwb.bookmall.admin.vo.UpdateAuthorityVo;
import cn.org.xwb.bookmall.model.constant.AccountConst;
import cn.org.xwb.bookmall.model.constant.ManagerConst;
import cn.org.xwb.bookmall.model.po.AllowMail;
import cn.org.xwb.bookmall.model.po.Authority;
import cn.org.xwb.bookmall.model.service.impl.AllowMailServiceImpl;
import cn.org.xwb.common.encrypt.annotation.des.DesEn;
import cn.org.xwb.common.encrypt.annotation.rsa.RsaDe;
import cn.org.xwb.common.encrypt.annotation.rsa.RsaDeObj;
import cn.org.xwb.common.encrypt.annotation.rsa.RsaDeParam;
import cn.org.xwb.common.encrypt.constant.EncryptConstant;
import cn.org.xwb.common.error.annotation.ServerErrorCatch;
import cn.org.xwb.common.mail.utils.MailUtil;
import cn.org.xwb.common.model.vo.RespResult;
import cn.org.xwb.common.valid.annotation.str.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("/manager")
public class AdminManagerController {

    @Autowired
    private AdminManagerService adminManagerService;

    /**
     * 分页获取允许登录的邮箱
     *
     * @return
     */
    @GetMapping("/allow/mails")
    @ServerErrorCatch
    @StrNotNull
    @RsaDe
    @IsLoginParam
    @DesEn
    public RespResult<Object> getAllowMailsPage(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @RequestParam(EncryptConstant.DES_KEY_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String desKey,
            @RequestParam("current")
            Integer current,
            @RequestParam("pageSize")
            Integer pageSize,
            @RequestParam(value = "disabled", required = false)
            Boolean disabled,
            @RequestParam(value = "match", required = false)
            String match
    ) {
        return adminManagerService.getAllowMailsPage(current, pageSize, disabled, match);
    }

    @Autowired
    private AllowMailServiceImpl allowMailService;

    @Autowired
    private MailUtil mailUtil;

    @PostMapping("/allow/mails/add")
    @ServerErrorCatch
    @StrNotNull
    @RsaDe
    @IsLoginParam
    @Transactional
    public RespResult<Object> addAllowMails(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @RequestParam("mail") @StrNotNullParam @RsaDeParam
            String mail,
            @RequestParam("disabled")
            Boolean disabled
    ) {
        if (!mailUtil.mailIsLegal(mail)) {
            return RespResult.fail("邮箱不合法");
        }
        LambdaQueryWrapper<AllowMail> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AllowMail::getMail, mail);
        AllowMail one = allowMailService.getOne(wrapper);
        if (Objects.nonNull(one)) {
            return RespResult.fail("请勿重复添加");
        }
        AllowMail allowMail = new AllowMail();
        allowMail.setMail(mail);
        allowMail.setDisabled(disabled);
        int res = allowMailService.getBaseMapper().insert(allowMail);
        if (res < 1) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("添加管理员邮箱失败");
        }
        List<AllowMail> allowMails = allowMailService.findAndCacheAll();
        if (Objects.isNull(allowMails)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("添加管理员邮箱失败");
        }
        return RespResult.success("添加管理员邮箱成功");
    }

    @PostMapping("/allow/mails/del")
    @ServerErrorCatch
    @StrNotNull
    @RsaDe
    @IsLoginParam
    @Transactional
    public RespResult<Object> delAllowMails(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @RequestParam("id")
            Integer id
    ) {
        boolean res = allowMailService.removeById(id);
        if (!res) return RespResult.fail("删除管理员邮箱失败，请稍后重新尝试");
        // 成功，刷新缓存
        List<AllowMail> allowMails = allowMailService.findAndCacheAll();
        if (Objects.isNull(allowMails)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("删除管理员邮箱失败，请稍后重新尝试");
        }
        return RespResult.success("删除管理员邮箱成功");
    }

    @PostMapping("/allow/mails/update")
    @ServerErrorCatch
    @StrNotNull
    @RsaDe
    @IsLoginParam
    @Transactional
    public RespResult<Object> updateAllowMails(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @RequestParam("id")
            Long id,
            @RequestParam("disabled")
            Boolean disabled
    ) {
        AllowMail allowMail = new AllowMail();
        allowMail.setId(id);
        allowMail.setDisabled(disabled);
        // 更新权限
        boolean updateRes = allowMailService.updateById(allowMail);
        if (!updateRes) return RespResult.fail("修改失败，请稍后重新尝试");
        // 成功，刷新缓存
        List<AllowMail> allowMails = allowMailService.findAndCacheAll();
        if (Objects.isNull(allowMails)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RespResult.fail("修改失败，请稍后重新尝试");
        }
        return RespResult.success("修改成功");
    }

    /**
     * 查询所有权限
     *
     * @param account
     * @param desKey
     * @return
     */
    @GetMapping("/authority/all")
    @ServerErrorCatch
    @StrNotNull
    @RsaDe
    @StrMaxLen
    @IsLoginParam
    @DesEn
    public RespResult<Object> getAllAuthority(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @RequestParam(EncryptConstant.DES_KEY_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String desKey
    ) {
        return adminManagerService.getAllAuthority();
    }

    @GetMapping("/authority/page")
    @ServerErrorCatch
    @StrNotNull
    @RsaDe
    @StrMaxLen
    @IsLoginParam
    @DesEn
    public RespResult<Object> getAuthorityPage(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @RequestParam(EncryptConstant.DES_KEY_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String desKey,
            @RequestParam("current")
            Integer current,
            @RequestParam("pageSize")
            Integer pageSize,
            @RequestParam(value = "disabled", required = false)
            Boolean disabled,
            @RequestParam(value = "nameMatch", required = false)
            @RsaDeParam @StrMaxLenParam(ManagerConst.AUTHORITY_NAME_MAX_LEN)
            String nameMatch,
            @RequestParam(value = "codeMatch", required = false)
            @RsaDeParam @StrMaxLenParam(ManagerConst.AUTHORITY_CODE_MAX_LEN)
            String codeMatch
    ) {
        return adminManagerService.getAuthorityPage(current, pageSize, disabled, nameMatch, codeMatch);
    }

    /**
     * 新增权限
     *
     * @param account
     * @param name
     * @param code
     * @param disabled
     * @param desc
     * @return
     */
    @PostMapping("/authority")
    @ServerErrorCatch
    @StrNotNull
    @RsaDe
    @StrMaxLen
    @IsLoginParam
    public RespResult<Object> addAuthority(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @RequestParam("name")
            @StrNotNullParam @RsaDeParam @StrMaxLenParam(ManagerConst.AUTHORITY_NAME_MAX_LEN)
            String name,
            @RequestParam("code")
            @StrNotNullParam @RsaDeParam @StrMaxLenParam(ManagerConst.AUTHORITY_CODE_MAX_LEN)
            String code,
            @RequestParam("disabled")
            Boolean disabled,
            @RequestParam("desc")
            @StrNotNullParam @RsaDeParam @StrMaxLenParam(ManagerConst.AUTHORITY_DESC_MAX_LEN)
            String desc
    ) {
        return adminManagerService.addAuthority(new Authority(null, name, code, disabled, desc));
    }

    /**
     * 修改权限
     *
     * @param updateAuthorityVo
     * @return
     */
    @PutMapping("/authority")
    @ServerErrorCatch
    @StrNotNull
    @RsaDe
    @StrMaxLen
    @IsLoginObj
    public RespResult<Object> updateAuthority(
            @RequestBody
            @StrNotNullObj @RsaDeObj @StrMaxLenObj
            UpdateAuthorityVo updateAuthorityVo
    ) {
        return adminManagerService.updateAuthority(Convert2PoUtil.genAuthority(updateAuthorityVo));
    }

    /**
     * 删除权限
     */
    @DeleteMapping("/authority")
    @ServerErrorCatch
    @StrNotNull
    @RsaDe
    @IsLoginParam
    public RespResult<Object> delAuthority(
            @RequestParam(AccountConst.ACCOUNT_PARAM_NAME)
            @StrNotNullParam @RsaDeParam
            String account,
            @RequestParam("id")
            Long id
    ) {
        return adminManagerService.delAuthority(id);
    }
}
